/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import DAO.exceptions.IllegalOrphanException;
import DAO.exceptions.NonexistentEntityException;
import DAO.exceptions.PreexistingEntityException;
import DAO.exceptions.RollbackFailureException;
import Entidad.*;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author David
 */
public class UsuarioDAO implements Serializable, DAOinterface {


    public void create(Usuario usuario, EntityManager em) throws Exception {
        if (usuario.getTareaCollection() == null) {
            usuario.setTareaCollection(new ArrayList<Tarea>());
        }
        if (usuario.getMensajeCollection() == null) {
            usuario.setMensajeCollection(new ArrayList<Mensaje>());
        }
        if (usuario.getMensajeCollection1() == null) {
            usuario.setMensajeCollection1(new ArrayList<Mensaje>());
        }
        if (usuario.getCargoCollection() == null) {
            usuario.setCargoCollection(new ArrayList<Cargo>());
        }       
        Proyecto idproyecto = usuario.getIdproyecto();
        if (idproyecto != null) {
            idproyecto = em.getReference(idproyecto.getClass(), idproyecto.getIdproyecto());
            usuario.setIdproyecto(idproyecto);
        }
        Rol idrol = usuario.getIdrol();
        if (idrol != null) {
            idrol = em.getReference(idrol.getClass(), idrol.getIdrol());
            usuario.setIdrol(idrol);
        }
        Collection<Tarea> attachedTareaCollection = new ArrayList<Tarea>();
        for (Tarea tareaCollectionTareaToAttach : usuario.getTareaCollection()) {
            tareaCollectionTareaToAttach = em.getReference(tareaCollectionTareaToAttach.getClass(), tareaCollectionTareaToAttach.getIdtarea());
            attachedTareaCollection.add(tareaCollectionTareaToAttach);
        }
        usuario.setTareaCollection(attachedTareaCollection);
        Collection<Mensaje> attachedMensajeCollection = new ArrayList<Mensaje>();
        for (Mensaje mensajeCollectionMensajeToAttach : usuario.getMensajeCollection()) {
                mensajeCollectionMensajeToAttach = em.getReference(mensajeCollectionMensajeToAttach.getClass(), mensajeCollectionMensajeToAttach.getIdmensaje());
                attachedMensajeCollection.add(mensajeCollectionMensajeToAttach);
        }
            usuario.setMensajeCollection(attachedMensajeCollection);
            Collection<Mensaje> attachedMensajeCollection1 = new ArrayList<Mensaje>();
            for (Mensaje mensajeCollection1MensajeToAttach : usuario.getMensajeCollection1()) {
                mensajeCollection1MensajeToAttach = em.getReference(mensajeCollection1MensajeToAttach.getClass(), mensajeCollection1MensajeToAttach.getIdmensaje());
                attachedMensajeCollection1.add(mensajeCollection1MensajeToAttach);
            }
            usuario.setMensajeCollection1(attachedMensajeCollection1);
            Collection<Cargo> attachedCargoCollection = new ArrayList<Cargo>();
            for (Cargo cargoCollectionCargoToAttach : usuario.getCargoCollection()) {
                cargoCollectionCargoToAttach = em.getReference(cargoCollectionCargoToAttach.getClass(), cargoCollectionCargoToAttach.getIdCargos());
                attachedCargoCollection.add(cargoCollectionCargoToAttach);
            }
            usuario.setCargoCollection(attachedCargoCollection);
            em.persist(usuario);
            if (idproyecto != null) {
                idproyecto.getUsuarioCollection().add(usuario);
                idproyecto = em.merge(idproyecto);
            }
            if (idrol != null) {
                idrol.getUsuarioCollection().add(usuario);
                idrol = em.merge(idrol);
            }
            for (Tarea tareaCollectionTarea : usuario.getTareaCollection()) {
                tareaCollectionTarea.getUsuarioCollection().add(usuario);
                tareaCollectionTarea = em.merge(tareaCollectionTarea);
            }
            for (Mensaje mensajeCollectionMensaje : usuario.getMensajeCollection()) {
                mensajeCollectionMensaje.getUsuarioCollection().add(usuario);
                mensajeCollectionMensaje = em.merge(mensajeCollectionMensaje);
            }
            for (Mensaje mensajeCollection1Mensaje : usuario.getMensajeCollection1()) {
                Usuario oldRemitenteOfMensajeCollection1Mensaje = mensajeCollection1Mensaje.getRemitente();
                mensajeCollection1Mensaje.setRemitente(usuario);
                mensajeCollection1Mensaje = em.merge(mensajeCollection1Mensaje);
                if (oldRemitenteOfMensajeCollection1Mensaje != null) {
                    oldRemitenteOfMensajeCollection1Mensaje.getMensajeCollection1().remove(mensajeCollection1Mensaje);
                    oldRemitenteOfMensajeCollection1Mensaje = em.merge(oldRemitenteOfMensajeCollection1Mensaje);
                }
            }
            for (Cargo cargoCollectionCargo : usuario.getCargoCollection()) {
                Usuario oldUsuarioOfCargoCollectionCargo = cargoCollectionCargo.getUsuario();
                cargoCollectionCargo.setUsuario(usuario);
                cargoCollectionCargo = em.merge(cargoCollectionCargo);
                if (oldUsuarioOfCargoCollectionCargo != null) {
                    oldUsuarioOfCargoCollectionCargo.getCargoCollection().remove(cargoCollectionCargo);
                    oldUsuarioOfCargoCollectionCargo = em.merge(oldUsuarioOfCargoCollectionCargo);
                }
            }
            
    }

    public void edit(Usuario usuario, EntityManager em)  {
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getCorreo());
            Proyecto idproyectoOld = persistentUsuario.getIdproyecto();
            Proyecto idproyectoNew = usuario.getIdproyecto();
            Rol idrolOld = persistentUsuario.getIdrol();
            Rol idrolNew = usuario.getIdrol();
            Collection<Tarea> tareaCollectionOld = persistentUsuario.getTareaCollection();
            Collection<Tarea> tareaCollectionNew = usuario.getTareaCollection();
            Collection<Mensaje> mensajeCollectionOld = persistentUsuario.getMensajeCollection();
            Collection<Mensaje> mensajeCollectionNew = usuario.getMensajeCollection();
            Collection<Mensaje> mensajeCollection1Old = persistentUsuario.getMensajeCollection1();
            Collection<Mensaje> mensajeCollection1New = usuario.getMensajeCollection1();
            Collection<Cargo> cargoCollectionOld = persistentUsuario.getCargoCollection();
            Collection<Cargo> cargoCollectionNew = usuario.getCargoCollection();
            List<String> illegalOrphanMessages = null;
            for (Mensaje mensajeCollection1OldMensaje : mensajeCollection1Old) {
                if (!mensajeCollection1New.contains(mensajeCollection1OldMensaje)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Mensaje " + mensajeCollection1OldMensaje + " since its remitente field is not nullable.");
                }
            }
            for (Cargo cargoCollectionOldCargo : cargoCollectionOld) {
                if (!cargoCollectionNew.contains(cargoCollectionOldCargo)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Cargo " + cargoCollectionOldCargo + " since its usuario field is not nullable.");
                }
            }
            if (idproyectoNew != null) {
                idproyectoNew = em.getReference(idproyectoNew.getClass(), idproyectoNew.getIdproyecto());
                usuario.setIdproyecto(idproyectoNew);
            }
            if (idrolNew != null) {
                idrolNew = em.getReference(idrolNew.getClass(), idrolNew.getIdrol());
                usuario.setIdrol(idrolNew);
            }
            if(tareaCollectionNew != null) {
            Collection<Tarea> attachedTareaCollectionNew = new ArrayList<Tarea>();
            for (Tarea tareaCollectionNewTareaToAttach : tareaCollectionNew) {
                tareaCollectionNewTareaToAttach = em.getReference(tareaCollectionNewTareaToAttach.getClass(), tareaCollectionNewTareaToAttach.getIdtarea());
                attachedTareaCollectionNew.add(tareaCollectionNewTareaToAttach);
            }
            tareaCollectionNew = attachedTareaCollectionNew;
            usuario.setTareaCollection(tareaCollectionNew);
            }
            
            if(mensajeCollectionNew != null) {
            Collection<Mensaje> attachedMensajeCollectionNew = new ArrayList<Mensaje>();
            for (Mensaje mensajeCollectionNewMensajeToAttach : mensajeCollectionNew) {
                mensajeCollectionNewMensajeToAttach = em.getReference(mensajeCollectionNewMensajeToAttach.getClass(), mensajeCollectionNewMensajeToAttach.getIdmensaje());
                attachedMensajeCollectionNew.add(mensajeCollectionNewMensajeToAttach);
            }
            mensajeCollectionNew = attachedMensajeCollectionNew;
            usuario.setMensajeCollection(mensajeCollectionNew);
            }
            
            if(mensajeCollection1New != null) {
            Collection<Mensaje> attachedMensajeCollection1New = new ArrayList<Mensaje>();
            for (Mensaje mensajeCollection1NewMensajeToAttach : mensajeCollection1New) {
                mensajeCollection1NewMensajeToAttach = em.getReference(mensajeCollection1NewMensajeToAttach.getClass(), mensajeCollection1NewMensajeToAttach.getIdmensaje());
                attachedMensajeCollection1New.add(mensajeCollection1NewMensajeToAttach);
            }
            mensajeCollection1New = attachedMensajeCollection1New;
            usuario.setMensajeCollection1(mensajeCollection1New);
            }
            if(cargoCollectionNew != null) {
            Collection<Cargo> attachedCargoCollectionNew = new ArrayList<Cargo>();
            for (Cargo cargoCollectionNewCargoToAttach : cargoCollectionNew) {
                cargoCollectionNewCargoToAttach = em.getReference(cargoCollectionNewCargoToAttach.getClass(), cargoCollectionNewCargoToAttach.getIdCargos());
                attachedCargoCollectionNew.add(cargoCollectionNewCargoToAttach);
            }
            cargoCollectionNew = attachedCargoCollectionNew;
            usuario.setCargoCollection(cargoCollectionNew);
            }
            
            usuario = em.merge(usuario);
            if (idproyectoOld != null && !idproyectoOld.equals(idproyectoNew)) {
                idproyectoOld.getUsuarioCollection().remove(usuario);
                idproyectoOld = em.merge(idproyectoOld);
            }
            if (idproyectoNew != null && !idproyectoNew.equals(idproyectoOld)) {
                idproyectoNew.getUsuarioCollection().add(usuario);
                idproyectoNew = em.merge(idproyectoNew);
            }
            if (idrolOld != null && !idrolOld.equals(idrolNew)) {
                idrolOld.getUsuarioCollection().remove(usuario);
                idrolOld = em.merge(idrolOld);
            }
            if (idrolNew != null && !idrolNew.equals(idrolOld)) {
                idrolNew.getUsuarioCollection().add(usuario);
                idrolNew = em.merge(idrolNew);
            }
            for (Tarea tareaCollectionOldTarea : tareaCollectionOld) {
                if (!tareaCollectionNew.contains(tareaCollectionOldTarea)) {
                    tareaCollectionOldTarea.getUsuarioCollection().remove(usuario);
                    tareaCollectionOldTarea = em.merge(tareaCollectionOldTarea);
                }
            }
            if(tareaCollectionNew != null) {
               for (Tarea tareaCollectionNewTarea : tareaCollectionNew) {
                if (!tareaCollectionOld.contains(tareaCollectionNewTarea)) {
                    tareaCollectionNewTarea.getUsuarioCollection().add(usuario);
                    tareaCollectionNewTarea = em.merge(tareaCollectionNewTarea);
                }
               } 
            }
            
            for (Mensaje mensajeCollectionOldMensaje : mensajeCollectionOld) {
                if (!mensajeCollectionNew.contains(mensajeCollectionOldMensaje)) {
                    mensajeCollectionOldMensaje.getUsuarioCollection().remove(usuario);
                    mensajeCollectionOldMensaje = em.merge(mensajeCollectionOldMensaje);
                }
            }
            
            if(mensajeCollectionNew != null) {
               for (Mensaje mensajeCollectionNewMensaje : mensajeCollectionNew) {
                if (!mensajeCollectionOld.contains(mensajeCollectionNewMensaje)) {
                    mensajeCollectionNewMensaje.getUsuarioCollection().add(usuario);
                    mensajeCollectionNewMensaje = em.merge(mensajeCollectionNewMensaje);
                }
            } 
            }
            if(mensajeCollection1New!= null) {
               for (Mensaje mensajeCollection1NewMensaje : mensajeCollection1New) {
                if (!mensajeCollection1Old.contains(mensajeCollection1NewMensaje)) {
                    Usuario oldRemitenteOfMensajeCollection1NewMensaje = mensajeCollection1NewMensaje.getRemitente();
                    mensajeCollection1NewMensaje.setRemitente(usuario);
                    mensajeCollection1NewMensaje = em.merge(mensajeCollection1NewMensaje);
                    if (oldRemitenteOfMensajeCollection1NewMensaje != null && !oldRemitenteOfMensajeCollection1NewMensaje.equals(usuario)) {
                        oldRemitenteOfMensajeCollection1NewMensaje.getMensajeCollection1().remove(mensajeCollection1NewMensaje);
                        oldRemitenteOfMensajeCollection1NewMensaje = em.merge(oldRemitenteOfMensajeCollection1NewMensaje);
                    }
                }
            } 
            }
            if(cargoCollectionNew != null) {
                for (Cargo cargoCollectionNewCargo : cargoCollectionNew) {
                if (!cargoCollectionOld.contains(cargoCollectionNewCargo)) {
                    Usuario oldUsuarioOfCargoCollectionNewCargo = cargoCollectionNewCargo.getUsuario();
                    cargoCollectionNewCargo.setUsuario(usuario);
                    cargoCollectionNewCargo = em.merge(cargoCollectionNewCargo);
                    if (oldUsuarioOfCargoCollectionNewCargo != null && !oldUsuarioOfCargoCollectionNewCargo.equals(usuario)) {
                        oldUsuarioOfCargoCollectionNewCargo.getCargoCollection().remove(cargoCollectionNewCargo);
                        oldUsuarioOfCargoCollectionNewCargo = em.merge(oldUsuarioOfCargoCollectionNewCargo);
                    }
                }
            }
            }
            
    }

    public void destroy(String id, EntityManager em) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
            Usuario usuario;
            usuario = em.getReference(Usuario.class, id);
            usuario.getCorreo();
            List<String> illegalOrphanMessages = null;
            Collection<Mensaje> mensajeCollection1OrphanCheck = usuario.getMensajeCollection1();
            for (Mensaje mensajeCollection1OrphanCheckMensaje : mensajeCollection1OrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Mensaje " + mensajeCollection1OrphanCheckMensaje + " in its mensajeCollection1 field has a non-nullable remitente field.");
            }
            Collection<Cargo> cargoCollectionOrphanCheck = usuario.getCargoCollection();
            for (Cargo cargoCollectionOrphanCheckCargo : cargoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Cargo " + cargoCollectionOrphanCheckCargo + " in its cargoCollection field has a non-nullable usuario field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Proyecto idproyecto = usuario.getIdproyecto();
            if (idproyecto != null) {
                idproyecto.getUsuarioCollection().remove(usuario);
                idproyecto = em.merge(idproyecto);
            }
            Rol idrol = usuario.getIdrol();
            if (idrol != null) {
                idrol.getUsuarioCollection().remove(usuario);
                idrol = em.merge(idrol);
            }
            Collection<Tarea> tareaCollection = usuario.getTareaCollection();
            for (Tarea tareaCollectionTarea : tareaCollection) {
                tareaCollectionTarea.getUsuarioCollection().remove(usuario);
                tareaCollectionTarea = em.merge(tareaCollectionTarea);
            }
            Collection<Mensaje> mensajeCollection = usuario.getMensajeCollection();
            for (Mensaje mensajeCollectionMensaje : mensajeCollection) {
                mensajeCollectionMensaje.getUsuarioCollection().remove(usuario);
                mensajeCollectionMensaje = em.merge(mensajeCollectionMensaje);
            }
            em.remove(usuario);
            
    }

    public List<Usuario> findUsuarioEntities(EntityManager em) {
        return findUsuarioEntities(true, -1, -1, em);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult, EntityManager em) {
        return findUsuarioEntities(false, maxResults, firstResult, em);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult, EntityManager em) {
       
        
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        
    }

    public Usuario findUsuario(String id, EntityManager em) {
        Usuario entity = null;
        try {
            entity = em.find(Usuario.class, id);
        }
        catch(Exception e) {
            entity = null;
        }
        finally {
            return entity;
        }
    }

    public int getUsuarioCount(EntityManager em) {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
    }
    
}
